/**
 * Name: Avinash Sridhar	G Number: G00861300
 */
package tcp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;

import tcp.Server.PhonebookEntry;

public class LookupService extends Thread{

	Socket mCurRequestSocket;

	ArrayList<PhonebookEntry> mPhonebook;
	int mClientSocketPort;
	int mChildrenSocketPort;
	int mParentSocketPort;



	public LookupService(Socket socket, ArrayList<PhonebookEntry> phonebook, int client_port, int children_port, int parent_port) {
		mCurRequestSocket = socket;
		mPhonebook = phonebook;
		mClientSocketPort = client_port;
		mChildrenSocketPort = children_port;
		mParentSocketPort = parent_port;
	}

	@Override
	public void run() {
		try {

			BufferedReader Reader = new BufferedReader( new InputStreamReader(mCurRequestSocket.getInputStream()) );
			String findWord = Reader.readLine();

			if (findWord.equals("exit"))
			{
				mCurRequestSocket.close();
				System.out.println("TCP server has received 'exit'status: TCP Clientconnection (only to the client that called 'exit') closed!");
			}
			else {
				System.out.println("Got TCP client request to find value: " + findWord);

				//Sleep for 5 seconds
				sleep(5000);

				//look up value in your phonebook
				String lookup_result =  lookup(findWord);

				if (!lookup_result.equals(""))	//FOUND MATCH(ES)
				{
					System.out.println("found matches!");

					WriteToPort(lookup_result, mClientSocketPort);    				
				}
				else if (lookup_result.equals("")) //NOT FOUND
				{
					if (mParentSocketPort > 0)	//if you have a parent
					{
						//forward request to parent via parent_port 
						InetAddress server_addr = InetAddress.getByName("localhost");
						Socket client = new Socket(server_addr, mParentSocketPort);

						BufferedReader ServerReader = new BufferedReader ( new InputStreamReader(client.getInputStream()) );
						PrintWriter ServerWriter = new PrintWriter(client.getOutputStream(), true);	

						System.out.println("TCP Server (acting as client now) is FWDing a request to the TCP parent... at "+ mParentSocketPort);
						ServerWriter.println(findWord);

						//wait for result from the parent.......
						String fwd_result = ServerReader.readLine();
						System.out.println("TCP Server (acting as client now) has received from TCP parent : " + fwd_result);

						client.close();
						ServerReader.close();
						ServerWriter.close();

						WriteToPort(fwd_result, mClientSocketPort);
					}
					else if (mParentSocketPort == -1)	//if you are the root node
					{
						//send answer to client via client_port "NEVER-FOUND"	USE CASE: DONE.
						System.out.println("TCP Server is sending a result back to the TCP client...");
						WriteToPort("No Match.", mClientSocketPort);
					}
				}
			}		    	
			mCurRequestSocket.close();
		} catch (IOException | InterruptedException e) {
			System.out.println("Interrupted socket connection...reset.");
			//e.printStackTrace();
		}
	}

	public void WriteToPort(String stringToWrite, int port)
	{
		try {
			System.out.println("TCP Server is replying to child " + mCurRequestSocket.getLocalPort());

			PrintWriter Writer = new PrintWriter(mCurRequestSocket.getOutputStream(), true);

			Writer.println(stringToWrite);
			Writer.close();

		} catch (IOException e) 
		{ e.printStackTrace(); }
	}

	public String lookup( String searchWord )
	{	
		System.out.println("looking up '" + searchWord + "' .....");

		String[] fullName = searchWord.split(" ");
		String result = "";
		boolean firstNameMatch;
		boolean lastNameMatch;

		//look for the entry		
		for (PhonebookEntry temp : mPhonebook) 
		{
			if (temp.mFirstName != null && temp.mLastName != null)
			{
				firstNameMatch = ( temp.mFirstName.equalsIgnoreCase(fullName[0]) || fullName[0].equalsIgnoreCase("*") );
				lastNameMatch = ( temp.mLastName.equalsIgnoreCase(fullName[1]) || fullName[1].equalsIgnoreCase("*") );
				if (firstNameMatch && lastNameMatch)
				{
					result += temp.mFirstName + " " + temp.mLastName + " " + temp.mPhoneNumber + "%";
				}
			}
		}
		return result;
	}

}
